/**
 * com.monte.query.QueryExecutor.java
 * 2013-03-04
 */
package com.monte.persistence;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import com.monte.common.Pagination;
import com.monte.persistence.command.MyBatisExecuteCountCommand;
import com.monte.persistence.command.MyBatisPaginationQueryCommand;
import com.monte.persistence.command.MyBatisQueryCommand;
import com.monte.persistence.command.MyBatisSelectOneCommand;
import com.monte.spring.ApplicationContextAware;

/**
 * 查询工具类实现(MyBatis)
 * @author FengMy
 * @since 2013-03-04
 */
@Component(value="queryExecutor")
public class QueryExecutorImpl extends SqlSessionDaoSupport implements QueryExecutor{
	@Autowired
	protected SqlSessionFactory sqlSessionFactory;
	@Autowired
	protected JdbcTemplate jdbcTemplate;
	@PersistenceContext
	private EntityManager entityManager;
	
	/**
	 * 创建并返回当前持久化上下文
	 * @return
	 */
	private CommandContext getCurrentCommandContext(){
		CommandContext ctx = new CommandContext();
		ctx.setEntityManager(entityManager);
		ctx.setJdbcTemplate(jdbcTemplate);
		ctx.setSqlSession(getSqlSession());
		ctx.setSqlSessionFactory(sqlSessionFactory);
		return ctx;
	}
	
	/**
	 * 获取spring中托管的bean
	 * @return
	 */
	public static QueryExecutor getInstance(){
		return ApplicationContextAware.getApplicationContext().getBean("queryExecutor", QueryExecutorImpl.class);
	}
	
	/**
	 * 执行分页查询(mybatis)
	 * @param mapper
	 * @param pagination
	 * @param param
	 * @return
	 */
	@Override
	@SuppressWarnings("unchecked")
	public <T> Pagination<T> execQuery(String mapper,Pagination<T> pagination,
			Object param) {
		return (Pagination<T>) new MyBatisPaginationQueryCommand<T>(mapper, pagination, param).execute(getCurrentCommandContext());
	}
	
	/**
	 * 执行列表查询(mybatis)
	 * @param mapper
	 * @param param
	 * @param type
	 * @return
	 */
	@Override
	public <T> List<T> execQuery(String mapper, Object param,Class<T> type) {
		return new MyBatisQueryCommand<T>(mapper, param).execute(getCurrentCommandContext());
	}
	
	/**
	 * 查询结果数(mybatis)
	 * @param mapper
	 * @param param
	 * @return
	 */
	@Override
	public int execCount(String mapper, Object param){
		return new MyBatisExecuteCountCommand(mapper, param).execute(getCurrentCommandContext());
	}

	
	/**
	 * 获取惟一结果(mybatis)
	 * @param mapper
	 * @param param
	 * @param type
	 * @return when result is null,should be throws exception
	 */
	@Override
	public <T> T selectSingleResult(String mapper, Object param,Class<T> type) {
		return new MyBatisSelectOneCommand<T>(mapper, param).execute(getCurrentCommandContext());
	}
	
	/**
	 * 查询惟一实体
	 * @param type
	 * @param id
	 * @return return null if result is null
	 */
	@Override
	public <T> T selectSingleEntity(Class<T> type,Object id){
		return entityManager.find(type, id);
	}
	
	/**
	 *调用命令
	 */
	@Override
	public Object callCommand(PersistenceCommand command) {
		if(command == null){
			return null;
		}
		return command.execute(getCurrentCommandContext());
	}
}
